"""
模拟卷积操作
"""
import torch
from torch.nn.functional import conv2d
#简言之，torch.nn.Conv2d 的 weight 无法自定义，而需要手动设置 weight 时需要用到 torch.nn.function.conv2d。

"""
torch.nn.Conv2d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True,padding_mode='zeros')
    in_channels-----输入通道数
    out_channels-------输出通道数
    kernel_size--------卷积核大小
    stride-------------步长
    padding---------是否对输入数据填充0

torch.nn.functional.conv2d(input,weight,bias=None,stride=1,padding=0,dilation=1,groups=1)
    input-------输入tensor大小（minibatch，in_channels，iH, iW）
    weight------权重大小（out_channels, [公式], kH, kW）
"""

input = torch.tensor([
    [1, 2, 0, 3, 1], [0, 1, 2, 3, 1], [1, 2, 1, 0, 0], [5, 2, 3, 1, 1], [2, 1, 0, 1, 1]
])
kernel = torch.tensor([
    [1, 2, 1], [0, 1, 0], [2, 1, 0]
])

# 重置形状 (torch.Size, List[_int], Tuple[_int, ...])
input = torch.reshape(input , (1,1,5,5))
kernel = torch.reshape(kernel , (1,1,3,3))

print(input.shape)
print(kernel.shape)

# 卷积操作
output = conv2d(input , kernel , stride=3)
print(output) # (5-3+3)/3 = 1

# 卷积操作
output = conv2d(input , kernel , stride=2)
print(output) # (5-3+2)/2 = 2

# 卷积操作
output = conv2d(input , kernel , stride=1)
print(output) # (5-3+1)/1 = 3